#include "zrpc/net/acceptor.h"

#include "zrpc/base/log.h"

namespace zrpc {
Acceptor::Acceptor(EventLoop *loop, const std::string &ip, int16_t port)
    : loop_(loop),
      channel_(loop_, socket::CreateTcpSocket(ip.c_str(), port)),
      sockfd_(channel_.Getfd()),
#ifndef _WIN64
      idlefd_(::open("/dev/null", O_RDONLY | O_CLOEXEC)),
#endif
      listenning_(false) {
#ifndef _WIN64
  assert(idlefd_ >= 0);
#endif
  channel_.SetReadCallback(std::bind(&Acceptor::HandleRead, this));
}

Acceptor::~Acceptor() {
  channel_.DisableAll();
  channel_.Remove();
  socket::Close(sockfd_);
}

void Acceptor::HandleRead() {
  loop_->AssertInLoopThread();
  int32_t connfd = socket::Accept(sockfd_);
  if (connfd >= 0) {
    if (new_connection_callback_) {
      socket::SetSocketNonBlock(connfd);
      new_connection_callback_(connfd);
    } else {
      socket::Close(sockfd_);
    }
  } else {
  }
}

void Acceptor::Listen() {
  loop_->AssertInLoopThread();
  listenning_ = true;
  channel_.EnableReading();
}
}  // namespace zrpc
